package lol.clann.minecraft.springboot.plugin.bukkit.command;

import com.google.auto.service.AutoService;
import com.ruoshui.utils.java.iterable.IterableUtils;
import lol.clann.minecraft.springboot.api.spi.sbp.ApplicationRunListener;
import lol.clann.minecraft.springboot.api.annotation.command.Command;
import lol.clann.minecraft.springboot.api.annotation.command.CommandDefine;
import lol.clann.minecraft.springboot.api.bukkit.utils.ServerUtils;
import lol.clann.minecraft.springboot.api.context.SpringContext;
import lombok.extern.slf4j.Slf4j;
import org.bukkit.Bukkit;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;
import java.util.*;

/**
 *
 * @author pyz
 * @date 2019/5/6 10:59 PM
 */
@Slf4j
@AutoService(ApplicationRunListener.class)
public class CommandRegister implements ApplicationRunListener {

    @Override
    public void started(SpringApplication application, ConfigurableApplicationContext context) {
        CommandHook commandHook = SpringContext.getBean(CommandHook.class);
        ServerUtils serverUtils = SpringContext.getBean(ServerUtils.class);

        List<Object> commands = commandHook.getCommands();
        List<CommandExecutor> allExecutor = new ArrayList<>();
        for (Object command : commands) {
            Class commandClass = ClassUtils.getUserClass(command);
            Method[] methods = ReflectionUtils.getUniqueDeclaredMethods(commandClass);
            for (Method method : methods) {
                if (method.isAnnotationPresent(Command.class)) {
                    allExecutor.add(SpringContext.createBean(CommandExecutor.class, new Object[]{command, method}));
                }
            }
        }
        Map<String, List<CommandExecutor>> map = IterableUtils.groupingBy(allExecutor, CommandExecutor::getName);
        for (Map.Entry<String, List<CommandExecutor>> en : map.entrySet()) {
            String command = en.getKey();
            LOGGER.info("register name:" + command);
            List<CommandExecutor> executors = en.getValue();
//          将order最小的排在前面,方便获取指令定义的注解
            executors.sort(Comparator.comparingInt(item -> item.getDefine().order()));
            CommandDispatcher dispatcher = CommandDispatcher.from(command, executors);
            dispatcher.forceHelp(Bukkit.getConsoleSender());
            CommandDefine define = executors.get(0).getDefine();
            CommandAdapter adpter = SpringContext.createBean(CommandAdapter.class, new Object[]{dispatcher, define.name(), define.description(), define.usageMessage(), Arrays.asList(define.aliases())});
            serverUtils.getCommandMap().register(adpter.getName(), adpter);
        }
    }
}
